#include "stm32f10x.h"                  // Device header

// 延时函数，微秒作为单位，利用系统嘀嗒定时器，72MHz，一次嘀嗒 1/72 us
void Delay_us(uint16_t us)
{
    // 1. 装载一个计数值，72 * us
    SysTick->LOAD = 72 * us;

    // 2. 配置，使用系统时钟（1），计数结束不产生中断（0），使能定时器（1）
    SysTick->CTRL = SysTick_CTRL_CLKSOURCE | SysTick_CTRL_ENABLE;

    // 3. 等待计数值变为0，判断CTRL标志位COUNTFLAG是否为1
    while ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG) == 0)
    {}

    // 4. 关闭定时器
    SysTick->CTRL &= ~SysTick_CTRL_ENABLE;
}

void Delay_ms(uint16_t ms)
{
    while (ms--)
    {
        Delay_us(1000);
    }
}

void Delay_s(uint16_t s)
{
    while (s--)
    {
        Delay_ms(1000);
    }
}

int main(void)
{
    // 1. GPIOA模块的时钟配置
    RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;

    // 2. GPIO PA0的工作模式配置：输出模式，推挽输出
    GPIOA->CRL &= ~GPIO_CRL_MODE0;
    GPIOA->CRL &= ~GPIO_CRL_CNF0;
    GPIOA->CRL |= (GPIO_CRL_MODE0_0 | GPIO_CRL_MODE0_1);

    // 2. GPIO PA1的工作模式配置：输出模式，推挽输出
    GPIOA->CRL &= ~GPIO_CRL_MODE1;
    GPIOA->CRL &= ~GPIO_CRL_CNF1;
    GPIOA->CRL |= (GPIO_CRL_MODE1_0 | GPIO_CRL_MODE1_1);

    // 2. GPIO PA8的工作模式配置：输出模式，推挽输出
    GPIOA->CRH &= ~GPIO_CRH_MODE8;
    GPIOA->CRH &= ~GPIO_CRH_CNF8;
    GPIOA->CRH |= (GPIO_CRH_MODE8_0 | GPIO_CRH_MODE8_1);

    // 3. PA0, PA1, PA8输出高电平, 熄灭LED
    GPIOA->ODR |= GPIO_ODR_ODR0;
    GPIOA->ODR |= GPIO_ODR_ODR1;
    GPIOA->ODR |= GPIO_ODR_ODR8;

    while(1)
    {
        GPIOA->ODR &= ~GPIO_ODR_ODR0;
        Delay_ms(500);
        GPIOA->ODR |= GPIO_ODR_ODR0;

        GPIOA->ODR &= ~GPIO_ODR_ODR1;
        Delay_ms(500);
        GPIOA->ODR |= GPIO_ODR_ODR1;

        GPIOA->ODR &= ~GPIO_ODR_ODR8;
        Delay_ms(500);
        GPIOA->ODR |= GPIO_ODR_ODR8;
    }
}
